package com.tdcoding.chat.configure;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.tdcoding.chat.action.BaseAction;
import com.tdcoding.chat.action.common.ActionFilter;
import com.tdcoding.chat.action.common.ActionMapper;
import com.tdcoding.chat.helper.Logger;
import com.tdcoding.chat.manager.DBManager;
import com.tdcoding.chat.manager.RedisManager;

public class Configuration {
	private static final String TAG = "Configuration";
	public static final String RESOURCES_PATH = System.getProperty("user.dir")+"\\resources\\";
	public static final String ACTION_MAPPING = RESOURCES_PATH+"actionMapping.xml";
	private static Configuration configuration;

	private ActionMapper actionMapper;

	public static Configuration getInstance() {
		if (configuration == null) {
			configuration = new Configuration();
		}
		return configuration;
	}

	private Configuration() {
		try {
			DBManager.initDBManager(this);
			RedisManager.initRedisManager(this);
			configActionMapping();
		} catch (Exception e) {
			e.printStackTrace();
			Logger.println(this, "err", e);
		}
	}

	public SqlSession configDBMapping() throws IOException {
		Reader reader = Resources.getResourceAsReader("dbaseMapping.xml");
		SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
		return ssf.openSession();
	}

	public Document configRedis() throws IOException {
		File redisFile =Resources.getResourceAsFile("redis.xml");
		if (!redisFile.exists()) {
			return null;
		}
		try {
			Logger.println(TAG, "configRedis  ", redisFile.getAbsolutePath());
			return Jsoup.parse(redisFile, "UTF-8");
		} catch (IOException e) {
			Logger.println(TAG, "configRedis err", e);
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 加载控制器
	 * 
	 * @param xmlPath
	 * @throws Exception
	 */
	public void configActionMapping() throws Exception {
		actionMapper = ActionMapper.getInstance();
		File actionFile =new File(ACTION_MAPPING);
		Document document = Jsoup.parse(actionFile, "UTF-8");
		Elements elements = (Elements) document.getElementsByTag("action");
		for (Element element : elements) {
			Element nameNode = element.getElementsByTag("action-name").first();
			Element classNode = element.getElementsByTag("action-class").first();
			if (classNode == null || !classNode.hasText()) {
				continue;
			}

			Elements filterNodes = element.getElementsByTag("action-filter");
			ArrayList<ActionFilter> lBaseFilters = new ArrayList<ActionFilter>();
			for (Element filterNode : filterNodes) {
				Element clazzNode = filterNode.getElementsByTag("filter-class").first();
				Element fnameNode = filterNode.getElementsByTag("filter-name").first();
				Element contentNode = filterNode.getElementsByTag("filter-content").first();
				if (!clazzNode.hasText()) {
					continue;
				}
				Class<?> actionClazz = Class.forName(clazzNode.text());
				ActionFilter baseFilter = (ActionFilter) actionClazz.newInstance();
				baseFilter.setName(fnameNode.text());
				baseFilter.setContent(contentNode.text());
				lBaseFilters.add(baseFilter);
			}
			Class<?> actionClazz = Class.forName(classNode.text());
			BaseAction baseAction = (BaseAction) actionClazz.newInstance();
			actionMapper.addActionContext(nameNode.text(), baseAction, lBaseFilters);
//			Logger.println(this, "configMapping", baseAction);
		}
	}

	public static void main(String[] args) {
		try {
			new Configuration();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// Document document;
		// try {
		// document = Jsoup.parse(new File(REDIS_CONFIGURE), "UTF-8");
		// Element maxIdle = document.getElementsByTag("maxIdle").first();
		// Element maxWait = document.getElementsByTag("maxWait").first();
		// Element maxActive = document.getElementsByTag("maxActive").first();
		// Element testOnBorrow =
		// document.getElementsByTag("maxActive").first();
		// Element testOnReturn =
		// document.getElementsByTag("testOnReturn").first();
		// Element testWhileIdle =
		// document.getElementsByTag("testWhileIdle").first();
		// Element numTestsPerEvictionRun =
		// document.getElementsByTag("numTestsPerEvictionRun").first();
		// Element minEvictableIdleTimeMillis =
		// document.getElementsByTag("minEvictableIdleTimeMillis").first();
		// Element timeBetweenEvictionRunsMillis =
		// document.getElementsByTag("timeBetweenEvictionRunsMillis").first();
		// Logger.println(TAG,maxIdle.text());
		// Logger.println(TAG,maxWait.text());
		// Logger.println(TAG,maxActive.text());
		// Logger.println(TAG,testOnBorrow.text());
		// Logger.println(TAG,testOnReturn.text());
		// Logger.println(TAG,testWhileIdle.text());
		// Logger.println(TAG,numTestsPerEvictionRun.text());
		// Logger.println(TAG,minEvictableIdleTimeMillis.text());
		// Logger.println(TAG,timeBetweenEvictionRunsMillis.text());
		// Elements elements=document.children();
		// for (Element element : elements) {
		// String host = element.getElementsByTag("host").first().text();
		// String pwd = element.getElementsByTag("pwd").first().text();
		// int port =
		// Integer.parseInt(element.getElementsByTag("port").first().text());
		// int timeout =
		// Integer.parseInt(element.getElementsByTag("timeout").first().text());
		// int weight =
		// Integer.parseInt(element.getElementsByTag("weight").first().text());
		// Logger.println(TAG,"for",host,pwd,port,timeout,weight);
		// }
		// } catch (IOException e) {
		// e.printStackTrace();
		// }

	}
}
